import 'dart:async';

import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:sgy_flutter/ble/errors.dart';
import 'package:sgy_flutter/extensions/get.dart';

mixin BleState on GetxController{
  StreamSubscription? _leftDeviceReadySubscription;
  StreamSubscription? _leftConnectionStateSubscription;
  bool _leftDeviceReady = false;

  StreamSubscription? _rightDeviceReadySubscription;
  StreamSubscription? _rightConnectionStateSubscription;
  bool _rightDeviceReady = false;

  /**
   * 指的是设备是否是双边设备
   */
  Rx<bool> isDoubleSlide = Rx(false);

  /**
   * 指的是UI上显示是否是双边，一方断开则变成单边模式
   */
  Rx<bool> isDoubleSlideMode = Rx(false);

  /**
   * 设备是否就绪，无论单双边，只要有一方是可用的，则UI上可用
   */
  Rx<bool> ready = Rx(false);

  @override
  void onInit() {
    _leftDeviceReadySubscription = bleManager.deviceReady.listen(_onLeftDeviceReadyChanged);
    _leftConnectionStateSubscription = bleManager.connectionState.listen(onLeftDeviceConnectionStateChanged);

    _rightDeviceReadySubscription = rightBleManager?.deviceReady.listen(_onRightDeviceReadyChanged);
    _rightConnectionStateSubscription = rightBleManager?.connectionState.listen(onLeftDeviceConnectionStateChanged);

    if (bleManager.deviceModel?.isDoubleSlide == true || rightBleManager?.deviceModel?.isDoubleSlide == true){
      isDoubleSlide(true);
    }
    _leftDeviceReady = bleManager.isReady.value;
    _rightDeviceReady = rightBleManager?.isReady.value == true;
    // _onLeftDeviceReadyChanged(_leftDeviceReady);
    if (isDoubleSlide.value){
      isDoubleSlideMode(_leftDeviceReady && _rightDeviceReady);
      this.ready(_leftDeviceReady || _rightDeviceReady);
      // _onRightDeviceReadyChanged(_rightDeviceReady);
    }else{
      this.ready(bleManager.isReady.value);
    }


    super.onInit();
  }


  void _onLeftDeviceReadyChanged(bool ready){
    printInfo(info: "_onLeftDeviceReadyChanged:$ready");
    _leftDeviceReady = ready;
    if (isDoubleSlide.value){
      isDoubleSlideMode(_leftDeviceReady && _rightDeviceReady);
      this.ready(_leftDeviceReady || _rightDeviceReady);
    }else{
      this.ready(ready);
    }
    if (ready){
      onLeftDeviceReady();
    }else{
      onLeftDeviceUnavailable();
    }
  }

  void _onRightDeviceReadyChanged(bool ready){
    _rightDeviceReady = ready;
    if (isDoubleSlide.value){
      isDoubleSlideMode(_leftDeviceReady && _rightDeviceReady);
      this.ready(_leftDeviceReady || _rightDeviceReady);
    }else{
      this.ready(ready);
    }
    if (ready){
      onRightDeviceReady();
    }else{
      onRightDeviceUnavailable();
    }
  }

  void onLeftDeviceReady(){

  }

  void onLeftDeviceUnavailable(){

  }

  void onLeftDeviceConnectionStateChanged(BluetoothConnectionState state){

  }

  void onRightDeviceReady(){

  }

  void onRightDeviceUnavailable(){

  }

  void onRightDeviceConnectionStateChanged(BluetoothConnectionState state){

  }

  /**
   * 双边设备
   * 只要有一个连接，就可以操作，如果两个都没有连接，则提示去连接
   */
  Future wrapperOperation({required FutureOr Function() leftOperation, required FutureOr Function()? rightOperation})async{
    if (isDoubleSlide.value){
      //两个都没有连接
      if (!_leftDeviceReady && !_rightDeviceReady){
        if (await bleManager.ensureDeviceConnected()){
          await wrapperOperation(leftOperation: leftOperation, rightOperation: rightOperation);
        }
      }else{
        EmptyWriteCharacteristicError? emptyWriteCharacteristicError;
        try{
          await leftOperation();
        }on EmptyWriteCharacteristicError catch(e){
          emptyWriteCharacteristicError = e;
        } catch(e){
          printError(info: "$leftOperation $e");
          rethrow;
        }
        try{
          await rightOperation?.call();
        }on EmptyWriteCharacteristicError catch(e){
          emptyWriteCharacteristicError = e;
        } catch(e){
          printError(info: "$leftOperation $e");
          rethrow;
        }
        if (emptyWriteCharacteristicError != null){
          showToast("请先移除充电线并重新连接".tr);
          throw emptyWriteCharacteristicError;
        }
      }
    }else{
      if (await bleManager.ensureDeviceConnected()) {
        try{
          await leftOperation();
        }on EmptyWriteCharacteristicError catch(e){
          showToast("请先移除充电线并重新连接".tr);
          rethrow;
        } catch(e){
          printError(info: "$leftOperation $e");
          rethrow;
        }
      }
    }
  }

  @override
  void onClose() {
    _leftDeviceReadySubscription?.cancel();
    _leftConnectionStateSubscription?.cancel();
    _rightDeviceReadySubscription?.cancel();
    _rightConnectionStateSubscription?.cancel();
    super.onClose();
  }
}